const cache = (window.xs_loadComponent_cache = window.xs_loadComponent_cache || {});
const loading = (window.xs_loadComponent_loading = window.xs_loadComponent_loading || {});

function loadJs(url, callback) {
  const script = document.createElement("script");
  script.type = "text/javascript";
  if (script.readyState) {
    script.onreadystatechange = function () {
      if (script.readyState == "loaded" || script.readyState == "complete") {
        script.onreadystatechange = null;
        callback();
      }
    };
  } else {
    script.onload = function () {
      callback();
    };
  }
  script.src = url;
  document.body.appendChild(script);
}

function waitingForLoading(url) {
  return new Promise((resolve, reject) => {
    let c = () => {
      if (!loading[url]) return resolve();
      else setTimeout(c, 50);
    };
    c();
  });
}

function loadJsAsync(url) {
  return new Promise(async (resolve, reject) => {
    if (cache[url]) return resolve();
    if (loading[url]) {
      await waitingForLoading(url);
      return resolve();
    }
    loading[url] = true;
    loadJs(url, function () {
      resolve();
      cache[url] = true;
      loading[url] = false;
    });
  });
}

function loadComponent(scopeModule, prop = "default", forceUrl) {
  let [scope, ...module] = scopeModule.split("/");
  module = ["."].concat(module).join("/");
  return async () => {
    let url = forceUrl || `/${scope}/remoteEntry.js`;
    await loadJsAsync(url);
    const factory = await window[scope].get(module);
    const Module = factory();
    let s = Module[prop];
    if (s instanceof Function) return s();
    return s;
  };
}

window.loadComponent = loadComponent;